#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>

void
error(char *msg)
{
	perror(msg);
	exit(1);
}

void dostuff(int sock)
{
	int n;
	char buffer[256];

	/*  Set buffer for client requests  */
	bzero(buffer, 256);
	n = read(sock, buffer, 255);
	if(n < 0)
		error("ERROR: Failed to read from socket");

	/*  Display Client's Message  */
	printf("Client's Message is: %s\n", buffer);

	/*  Reply on clien't message  */
	n = write(sock, "Your Request is accepted", 24);
	if(n < 0)
		error("ERROR: Failed to write on socket");
}

int main(int argc, char *argv[])
{
	int sockfd, newsockfd, portno;
	pid_t pid;
	socklen_t clilen;
	struct sockaddr_in serv_addr, cli_addr;

	if(argc < 2) {
		fprintf(stderr,"ERROR: Port is not provided\n");
		exit(1);
	}

	/*  Create Socket for Server  */
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd < 0)
		error("ERROR: Failed to create socket");

	/*  Clear Server Socket Structure  */
	bzero((char *) &serv_addr, sizeof(serv_addr));

	/*  Convert port no in passed as string to number  */
	portno = atoi(argv[1]);

	/*  Set internet address structure for serv_addr  */
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = portno;
	serv_addr.sin_addr.s_addr = INADDR_ANY;
	
	/*  bind server socket  */
	if ((bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))) < 0 )
		error("ERROR: Failed to bind server socket");
	
	/* Place server socket in listening mode  */
	listen(sockfd, 5);

	/*  Set client structure  */
	clilen = sizeof(cli_addr);

	/* Keep server running to handle multiple requests  */
	while(1) {
		newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
		if(newsockfd < 0)
			error("ERROR: Failed to accept client request");

		pid = fork();
		if(pid < 0)
			error("ERROR: Forking process");
	
		if(pid == 0) {
			close(sockfd);
			dostuff(newsockfd);
			exit(0);
		} else {
			close(newsockfd);
		}
	}

	close(sockfd);

	return 0;
}

